/**
 * @ Author: luoqi
 * @ Create Time: 2025-06-29 20:26
 * @ Modified by: luoqi
 * @ Modified time: 2025-07-14 04:41
 * @ Description: Custom string and memory operation function implementation
 */

#include "qstr.h"

// Compare two strings
int qstrcmp(const void *s1, const void *s2)
{
    const char *str1 = s1;
    const char *str2 = s2;

    while(*str1 != '\0' && *str2 != '\0' && *str1 == *str2) {
        str1++;
        str2++;
    }

    if(*str1 == *str2) {
        return 0;
    } else if(*str1 < *str2) {
        return -1;
    } else {
        return 1;
    }
}

void *qmemcpy(void *dest, const void *src, size_t n)
{
    uint8_t *d = dest;
    const uint8_t *s = src;

    if(d > s && d < s + n) {
        d += n - 1;
        s += n - 1;
        while(n--) {
            *d-- = *s--;
        }
    } else {
        if(n >= 8 && RB_IS_ALIGNED(s, 8) && RB_IS_ALIGNED(d, 8)) {
            uint64_t *d64 = (uint64_t *)d;
            const uint64_t *s64 = (const uint64_t *)s;
            while(n >= 8) {
                *d64++ = *s64++;
                n -= 8;
            }
            d = (uint8_t *)d64;
            s = (uint8_t *)s64;
        } else if(n >= 4 && RB_IS_ALIGNED(s, 4) && RB_IS_ALIGNED(d, 4)) {
            uint32_t *d32 = (uint32_t *)d;
            const uint32_t *s32 = (const uint32_t *)s;
            while(n >= 4) {
                *d32++ = *s32++;
                n -= 4;
            }
            d = (uint8_t *)d32;
            s = (uint8_t *)s32;
        }

        while(n--) {
            *d++ = *s++;
        }
    }

    return dest;
}

// Fill the destination memory area with the specified value
void *qmemset(void *ptr, int c, size_t n)
{
    if(ptr == NULL) {
        return NULL;
    }

    unsigned char *p = (unsigned char *)ptr;
    unsigned char uc = (unsigned char)c;

    for(size_t i = 0; i < n; i++) {
        p[i] = uc;
    }

    return ptr;
}

size_t qstrlen(const void *s)
{
    const char *str = s;
    if(str == NULL) {
        return 0;
    }
    const char *p = str;
    while(*p != '\0') {
        p++;
    }
    return p - str;
}

int qstr2num(const void *s)
{
    const char *str = s;
    if(str == NULL) {
        return 0;
    }
    int num = 0;
    while((*str != '\0') && ((*str >= '0') && (*str <= '9'))) {
        num = num * 10 + (*str - '0');
        str++;
    }
    return num;
}
